﻿#ifndef __QTUTILS_H__
#define __QTUTILS_H__

#include <iostream>
#include <string>
#include <vector>

#include <QString>
#include <QStringList>
#include <QDir>
#include <QUdpSocket>
#include <QDateTime>

#include <string>
#include <locale>
#include <codecvt>
////////////////////////////////////////////////////////////////////////////////
/// string utils
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief qstring2stdstring - convert QString to std::string (using local codec)
 *
 * @param s     - [in] QString
 *
 * @return
 *      std::string (local text codec)
 */
inline std::string qstring2stdstring(const QString& s)
{
    if( s.size() )
    {
        QByteArray baStr = s.toLocal8Bit();
        std::string stdstr = baStr.data();
        return stdstr;
    }
    else
    {
        return "";
    }
}

/**
 * @brief stdstring2qstring - convert std::string to QString
 *
 * @param s     - [in] std::string (local text codec)
 *
 * @return
 *      QString
 */
inline QString stdstring2qstring(const std::string& s)
{
    if( s.size() )
        return QString::fromLocal8Bit(s.c_str());
    else
        return QString();
}


/**
 * @brief qstring2utf8 - conver QString to std::string (utf-8)
 *
 * @param s     - [in] QString
 *
 * @return
 *      std::string (utf-8 encoded)
 */
inline std::string qstring2utf8(const QString& s)
{
    if( s.size() )
    {
        QByteArray baStr = s.toUtf8();
        std::string stdstr = baStr.data();
        return stdstr;
    }
    else
    {
        return "";
    }
}

inline std::string Unicode2UTF8(const std::wstring & wstr)
{
    std::string ret;
    try {
        std::wstring_convert< std::codecvt_utf8<wchar_t> > wcv;
        ret = wcv.to_bytes(wstr);
    } catch (const std::exception & e) {
        std::cerr << e.what() << std::endl;
    }
    return ret;
}

/**
 * @brief utf82qstring - convert std::string (utf-8) to QString
 *
 * @param s     - [in] std::string (utf-8)
 *
 * @return
 *      QString
 */
inline QString utf82qstring(const std::string& s)
{
    if( s.size() )
        return QString::fromUtf8(s.c_str());
    else
        return QString();
}


inline QStringList stdstringlist2qstringlist(const std::vector<std::string>& stringlist)
{
    QStringList l;

    for(auto i: stringlist)
    {
        l.push_back(stdstring2qstring(i));
    }

    return l;
}

inline std::vector<std::string> qstringlist2stdstringlist(const QStringList& stringlist)
{
    std::vector<std::string> l;

    for(auto i: stringlist)
    {
        l.push_back(qstring2stdstring(i));
    }

    return l;
}



inline std::string& str_tolower(std::string &s)
{
    for(size_t i=0; i < s.size(); i++) {
        s[i] = tolower(s[i]);
    }

    return s;
}

inline std::string file_extname(const std::string& fname)
{
    int idx = fname.find_last_of('.');
    if (idx == std::string::npos) return "";

    std::string ext_ = fname.substr(idx+1);
    std::string ext = str_tolower(ext_);
    return ext;
}

////////////////////////////////////////////////////////////////////////////////
/// Path utils
////////////////////////////////////////////////////////////////////////////////

int clearnDir(const QString& dPath);


////////////////////////////////////////////////////////////////////////////////
/// Network utils
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Get HTTP response from given URL address
 *      Ref:
 *          https://www.cnblogs.com/Travis990/p/4483538.html
 *          https://www.cnblogs.com/findumars/p/5574305.html
 *
 * @param url          - URL address
 * @param timeout      - access timeout value (default: 2.0 s)
 *
 * @return
 *      no empty string - response
 *      empty string    - can not access or timeouted
 */
QString GetHttpResponse(const QString& url, int timeout=2.0);

int GetWebDateTime(QDateTime& dt, int timeOut=20);

class QNetworkTime : QObject
{
    Q_OBJECT

public:
    QNetworkTime();
    virtual ~QNetworkTime();

    void getDateTime(QDateTime &dt) { dt = webTime; }
    int isTimeReaded(void) { return timeReaded; }

public slots:
    void connectSucess();
    void readingData();

protected:
    QUdpSocket udpsocket;
    QDateTime  webTime;
    int        timeReaded;
};

////////////////////////////////////////////////////////////////////////////////
/// System utils
////////////////////////////////////////////////////////////////////////////////

size_t getMemorySize( );


#endif // end of __QTUTILS_H__

